/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package conf2;

import conf2.net.IConnection;
import conf2.net.Message;
import conf2.ui.MainWindow;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.SwingWorker;

/**
 *
 * @author Administrator
 */
public class AsyncWaiter<T> extends SwingWorker<T, Void>
{

    public static interface Listener<T>
    {

        void completed(T result);
    }
    private final MainWindow mw;
    private final String waitMessage;
    private final IConnection conn;
    private final Class expectedReturn;
    private List<Listener> listeners = new LinkedList<Listener>();

    public AsyncWaiter(IConnection conn, Class expectedReturn, MainWindow mw, String waitMessage)
    {
        this.conn = conn;
        this.mw = mw;
        this.expectedReturn = expectedReturn;
        this.waitMessage = waitMessage;
    }

    public AsyncWaiter(IConnection conn, Class expectedReturn)
    {
        this.conn = conn;
        this.expectedReturn = expectedReturn;
        mw = null;
        waitMessage = null;
    }

    public void addListener(Listener l)
    {
        listeners.add(l);
    }

    @Override
    protected T doInBackground() throws Exception
    {
        if (mw != null) {
            mw.showCenteredWaitMessage(waitMessage);
        }

        T retVal;

        for (;;) {

            Message msg = conn.waitForNextMessage();
            if (msg.dataIsOfClass(expectedReturn)) {
                retVal = (T) msg.getData();
                break;
            } else {
                Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).severe(
                        "Waited for " + expectedReturn + ", got " + msg.getData().getClass());
            }
        }

        return retVal;
    }

    @Override
    protected void done()
    {
        if (mw != null) {
            mw.hideCenteredWaitMessage();
        }
        for (Listener l : listeners) {
            try {
                l.completed(get());
            } catch (InterruptedException ex) {
                Logger.getLogger(AsyncWaiter.class.getName()).log(Level.SEVERE, null, ex);
            } catch (ExecutionException ex) {
                Logger.getLogger(AsyncWaiter.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
}
